package com.duobaoyu.dby.supply.biz.producer;


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.duobaoyu.dby.common.core.constant.RocketMqCommonConstant;
import com.duobaoyu.dby.common.core.constant.StringPool;
import com.duobaoyu.dby.message.dto.MessageParam;
import com.duobaoyu.dby.message.dto.SendMessageDTO;
import com.duobaoyu.dby.message.enums.AcceptorTypEnum;
import com.duobaoyu.dby.message.enums.MessageTypeEnum;
import com.duobaoyu.dby.message.enums.SendChannelEnum;
import com.duobaoyu.dby.message.enums.SystemTypeEnum;
import com.duobaoyu.dby.supply.biz.processor.TransactionAfterPostProcessor;
import com.duobaoyu.dby.supply.biz.producer.constant.SupplyChainMQConstants;
import com.duobaoyu.dby.supply.biz.producer.message.*;
import com.duobaoyu.dby.supply.biz.service.refund.event.AfterSaleStateChangeEvent;
import com.duobaoyu.dby.supply.common.mq.remote.constants.BizMQConstants;
import com.duobaoyu.dby.supply.common.mq.remote.message.AfterSaleStateChangeMessage;
import com.duobaoyu.dby.supply.common.mq.remote.message.OrderAlterMessage;
import com.duobaoyu.dby.supply.core.rocketmq.constant.CommonTopicConstant;
import com.duobaoyu.dby.supply.core.rocketmq.producer.RocketMqProducer;
import com.duobaoyu.dby.supply.db.entity.message.MqMessage;
import com.duobaoyu.dby.supply.db.entity.order.Order;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 发送者
 *
 * @author fengshaoyu
 * @version 1.0.0
 * @date 2023/9/25 15:02
 */
@Component
@RefreshScope
@RequiredArgsConstructor
public class SupplyChainMQProducer extends TransactionAfterPostProcessor {

    @Value("${dby.order.exception-msg.jump-url}")
    private String jumpUrl;
    private final ObjectMapper objectMapper;
    private final RocketMqProducer rocketMqProducer;

    /**
     * 订单变动消息
     *
     * @param supplyTradeSn 交易号
     * @param serverName    业务方
     */
    public void orderAlterSend(String supplyTradeSn, String serverName) {
        OrderAlterMessage orderAlterMessage = OrderAlterMessage.builder().supplyTradeSn(supplyTradeSn).build();
        orderAlterMessage.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(BizMQConstants.OrderTopic.getTopic(serverName),
                BizMQConstants.OrderTopic.Tag.ORDER_ALTER,
                orderAlterMessage));
    }


    /**
     * 订单确认消息
     *
     * @param supplyTradeSn
     * @param orderSnList
     */
    public void orderConfirmSend(String supplyTradeSn, List<String> orderSnList) {
        OrderConfirmMessage orderConfirmMessage = OrderConfirmMessage
                .builder()
                .supplyTradeSn(supplyTradeSn)
                .orderSnList(orderSnList)
                .build();
        orderConfirmMessage.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.ORDER_TOPIC,
                SupplyChainMQConstants.SupplyChainTopic.OrderTag.ORDER_CONFIRM,
                orderConfirmMessage));
    }


    public void afterSaleApplicationMsgSend(String topic, String tag, AfterSaleStateChangeEvent afterSaleStateChangeEvent) {
        AfterSaleMessage afterSaleMessage = AfterSaleMessage.builder()
                .afterSaleSn(afterSaleStateChangeEvent.getAfterSaleSn())
                .afterSaleType(afterSaleStateChangeEvent.getAfterSaleType())
                .orderSn(afterSaleStateChangeEvent.getOrderSn())
                .afterSaleStatus(afterSaleStateChangeEvent.getAfterSaleStatus())
                .orderAutoCancel(afterSaleStateChangeEvent.getOrderAutoCancel())
                .refundSuccess(afterSaleStateChangeEvent.getRefundSuccess())
                .build();
        afterSaleMessage.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(topic, tag, afterSaleMessage));
    }


    public void afterSaleExternalMsgSend(String topic, String tag, AfterSaleStateChangeMessage message) {
		message.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(topic, tag, message));
    }

    /**
     * 取消订单申请售后消息
     *
     * @param supplyTradeSn
     * @param orderSnList
     */
    public void cancelOrderApplySalesSend(String supplyTradeSn, List<String> orderSnList) {
        ApplyAfterSaleMessage applyAfterSaleMessage = ApplyAfterSaleMessage
                .builder()
                .supplyTradeSn(supplyTradeSn)
                .orderSnList(orderSnList)
                .build();
        applyAfterSaleMessage.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.ORDER_TOPIC,
                SupplyChainMQConstants.SupplyChainTopic.AfterSaleTag.CANCEL_ORDER_APPLY_AFTER_SALE,
                applyAfterSaleMessage));
    }


    /**
     * 渠道消息发送
     *
     * @param channelMessageId
     */
    public void channelMessageSend(String channelMessageId) {
        if (StringUtils.isNotBlank(channelMessageId)) {
            ChannelMessage channelMessage = ChannelMessage
                    .builder()
                    .channelMessageId(channelMessageId)
                    .build();
            channelMessage.defaultDataFill();
            this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.CHANNEL_MESSAGE_TOPIC,
                    SupplyChainMQConstants.SupplyChainTopic.ChannelMessageTag.ORDER_MESSAGE_TAG,
                    channelMessage));
        }
    }

    /**
     * 发送清楚本地缓存消息
     *
     * @param object
     */
    public void sendDeleteLocalCacheMessage(Object object) {
        this.execute(() -> rocketMqProducer.asyncSendMessage(CommonTopicConstant.LocalCacheBroadcast.TOPIC,
                CommonTopicConstant.LocalCacheBroadcast.Tag.RESOURCE_LOCAL_CACHE_CHANGE_TAG,
                object));
    }

    /**
     * 发送系统操作日志
     *
     * @param systemLog
     */
    public void sendSystemLogMessage(String systemLog) {
        this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.SUPPLY_CHAIN_ADMIN_TOPIC,
                SupplyChainMQConstants.SupplyChainTopic.SupplyChainAdminTag.SYSTEM_LOG_TAG,
                systemLog));
    }

    @SneakyThrows
    public String retryMessage(MqMessage message) {
        final String prefix = "R";
        Object obj;
        if (JSONUtil.isTypeJSON(message.getMessage())) {
            obj = objectMapper.readValue(message.getMessage(), Object.class);
        } else {
            obj = StrUtil.replace(message.getMessage(), StringPool.QUOTE, StringPool.EMPTY);
        }
        SendStatus sendStatus;
        if (StringUtils.isBlank(message.getHashKey())) {
            sendStatus = rocketMqProducer.syncSendMessage(message.getTopic(), obj, message.getTag(), prefix.concat(message.getId().toString()), message.getMessageLinkId());
        } else {
            sendStatus = rocketMqProducer.syncSendOrderlyMessage(message.getTopic(), obj, message.getTag(), message.getHashKey(), prefix.concat(message.getId().toString()), message.getMessageLinkId());
        }
        return Optional.ofNullable(sendStatus).map(Enum::name).orElse(null);
    }

    /**
     * 发送补单消息
     */
    public void sendOrderRepairMessage(String orderSn) {
        OrderRepairMessage orderRepairMessage = OrderRepairMessage
                .builder()
                .orderSn(orderSn)
                .build();
        orderRepairMessage.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.SUPPLY_CHAIN_ADMIN_TOPIC,
                SupplyChainMQConstants.SupplyChainTopic.SupplyChainAdminTag.ORDER_REPAIR_TAG,
                orderRepairMessage));
    }

    /**
     * 同步订单额外信息
     *
     * @param orderExtendList
     */
    public void orderExtendSync(List<Order> orderExtendList) {
        List<OrderExtendSyncMessage.OrderExtendSync> orderExtendSyncList = orderExtendList.stream().map(item -> {
            OrderExtendSyncMessage.OrderExtendSync orderExtendSync = new OrderExtendSyncMessage.OrderExtendSync();
            orderExtendSync.setOrderSn(item.getOrderSn());
			orderExtendSync.setChannelCode(item.getChannelCode());
            orderExtendSync.setRechargeAccount(item.getRechargeAccount());
            return orderExtendSync;
        }).collect(Collectors.toList());
        OrderExtendSyncMessage orderExtendSyncMessage = OrderExtendSyncMessage
                .builder()
                .orderExtendSyncList(orderExtendSyncList)
                .build();
        orderExtendSyncMessage.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.ORDER_TOPIC,
                SupplyChainMQConstants.SupplyChainTopic.OrderTag.ORDER_EXTEND_SYNC,
                orderExtendSyncMessage));
    }

    public void sendAfterStateSync(String orderSn) {
        AfterStateCheckSyncMessage afterStateCheckSyncMessage = new AfterStateCheckSyncMessage();
        afterStateCheckSyncMessage.setOrderSn(orderSn);
        afterStateCheckSyncMessage.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.SUPPLY_CHAIN_ADMIN_TOPIC,
                SupplyChainMQConstants.SupplyChainTopic.AfterSaleTag.AFTER_SALES_STATE_CHECK,
                afterStateCheckSyncMessage));
    }


    /**
     * 发送售后站内信消息
     *
     * @param messageParam
     */
    public void sendAfterSaleMailMessage(MessageParam messageParam) {
        SendMessageDTO sendMessage = new SendMessageDTO();
        sendMessage.setMessageType(MessageTypeEnum.AFTER_SALES_MESSAGE);
        sendMessage.setSendChannel(SendChannelEnum.STATION_MESSAGE);
        sendMessage.setAcceptorType(AcceptorTypEnum.PLATFORM);
        sendMessage.setSystemType(SystemTypeEnum.MAIN_SYSTEM);
        rocketMqProducer.asyncSendMessage(RocketMqCommonConstant.MESSAGE_TOPIC, RocketMqCommonConstant.SEND_MESSAGE_TAG, sendMessage);
    }

    /**
     * 发送渠道商品售后站内信消息
     *
     * @param channelMessageId
     */
    public void sendChannelMessageRetryMessage(String channelMessageId) {
        rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.SUPPLY_CHAIN_ADMIN_TOPIC
                , SupplyChainMQConstants.SupplyChainTopic.SupplyChainAdminTag.CHANNEL_MESSAGE_RETRY_TAG, channelMessageId);
    }

    /**
     * 发送平台异常订单统计消息
     * @param paramMap
     */
    public void sendPlatformAbnormalOrdersMessage(Map<String, Object> paramMap) {
        // 消息通知平台
        SendMessageDTO sendMessage = new SendMessageDTO();
        sendMessage.setJumpUrl(jumpUrl);
        sendMessage.setMessageCodeStr("order_failed_warning_message");
        sendMessage.setMessageType(MessageTypeEnum.ORDER_MESSAGE);
        sendMessage.setSendChannel(SendChannelEnum.STATION_MESSAGE);
        sendMessage.setAcceptorType(AcceptorTypEnum.PLATFORM);
        sendMessage.setSystemType(SystemTypeEnum.MAIN_SYSTEM);
        //${startTime}至${endTime}的交易订单失败总数${orderCount}，请前往【供应链】管理后台系统查看详情
        sendMessage.setParamMap(paramMap);
        rocketMqProducer.asyncSendMessage(RocketMqCommonConstant.MESSAGE_TOPIC, RocketMqCommonConstant.SEND_MESSAGE_TAG, sendMessage);
    }

    /**
     * 发送短信消息
     * @param templateParam
     * @param receiverList 接收短信手机号码list
     */
    public void sendSmsMessage(Map<String, String> templateParam,List<String> receiverList) {
        SendMessageDTO sendMessage = new SendMessageDTO();
        sendMessage.setMessageType(MessageTypeEnum.WARNING_MESSAGE);
        //设置消息渠道为短信
        sendMessage.setSendChannel(SendChannelEnum.SMS_MESSAGE);
        //设置模版ID验证码短信可不传
        sendMessage.setTemplateId("613869");
        //短信接收人
        sendMessage.setReceiverList(receiverList);
        //设置短信模版参数
        sendMessage.setParams(templateParam);
        //发送到MQ
        rocketMqProducer.asyncSendMessage(RocketMqCommonConstant.MESSAGE_TOPIC, RocketMqCommonConstant.SEND_MESSAGE_TAG, sendMessage);
    }

    /**
     * 发送计算订单预估运费消息
     */
    public void sendOrderEstimateFreightCalcMessage(List<String> orderSnList) {
        if (CollectionUtils.isEmpty(orderSnList)) {
            return;
        }
        OrderEstimateFreightCalcMessage message = OrderEstimateFreightCalcMessage.builder().orderSnList(orderSnList).build();
        message.defaultDataFill();
        this.execute(() -> rocketMqProducer.asyncSendMessage(SupplyChainMQConstants.SupplyChainTopic.ORDER_TOPIC,
                SupplyChainMQConstants.SupplyChainTopic.OrderTag.ESTIMATE_FREIGHT_AMOUNT,
                message));
    }
}
